/*-------------------------------------------------------------------------
 *
 * strlcpy.c
 *	  用正确的方式实现 strncpy
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 *
 *
 * IDENTIFICATION
 *	  src/port/strlcpy.c
 *
 * 本文件来源于 OpenBSD，并用于不提供 strlcpy() 的平台。
 * OpenBSD 的版权条款如下。
 *-------------------------------------------------------------------------
 */

/*	$OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $	*/

/*
 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "c.h"


/*
 * 将 src 复制到大小为 siz 的字符串 dst。最多复制 siz-1 个字符。
 * 总是以 NUL 终止（除非 siz == 0）。
 * 返回 strlen(src)；如果 retval >= siz，则发生了截断。
 * 函数创建历史：  http://www.gratisoft.us/todd/papers/strlcpy.html
 */
size_t strlcpy(char *fc_dst, const char *fc_src, size_t fc_siz)
{
	char	   *fc_d = fc_dst;
	const char *fc_s = fc_src;
	size_t		fc_n = fc_siz;

	/* 尽可能多地复制字节 */
	if (fc_n != 0)
	{
		while (--fc_n != 0)
		{
			if ((*fc_d++ = *fc_s++) == '\0')
				break;
		}
	}

	/* dst 中空间不足，添加 NUL 并遍历剩余的 src */
	if (fc_n == 0)
	{
		if (fc_siz != 0)
			*fc_d = '\0';			/* 用 NUL 终止 dst */
		while (*fc_s++)
			;
	}

	return (fc_s - fc_src - 1);		/* 计数不包括NUL */
}
